-- implement the various contracts for hash maps

private import base;
private import sequences;
private import strings;
private import iterable;
private import updateable;
private import casting;

type map of (%k,%v) is alias of hash of (%k,%v);


-- macro for old hash notation
#hash { ?X } ==> hash of { X };
#hash{} ==> hash of {};

implementation equality over (hash of (%k,%v) where equality over %k 'n equality over %v) is {
  X=Y is hash_equal(X,Y);
} using {
  hash_equal(X,Y) is __hash_equal(X,Y,(=));
}

implementation sizeable over hash of (%s,%t) is {
  isEmpty(M) is __hash_empty(M);
  size(R) is integer(__hash_size(R));
}

implementation pPrint over hash of (%k,%v) where pPrint over %k 'n pPrint over %v is {
  ppDisp(M) is ppStr(__display(M));
}

implementation indexable over hash of (%k,%v) determines (%k,%v) is {
  _index(M,K) is __hashGet(M,K);
  _set_indexed(M,K,V) is __hashUpdate(M,K,V);
  _delete_indexed(M,K) is __hashDelete(M,K);
  _index_member(__hashGet(M,K)) from (M,K) where __hashContains(M,K);
}

implementation updateable over hash of (%k,%v) determines ((%k,%v)) is {
  _extend(L,(K,V)) is __hashUpdate(L,K,V);
  _merge(L,R) is __hash_merge(L,R);
  _delete(R,P) is __delete_from_hash(R,P);
  _update(R,M,F) is __update_into_hash(R,M,F);
};

implementation sequence over hash of (%k,%v) determines ((%k,%v)) is {
  _cons((K,V),H) is __hashUpdate(H,K,V);
  _apnd(H,(K,V)) is __hashUpdate(H,K,V);
  _nil() is __hashCreate();
  _empty() from X where __hash_empty(X);
  _pair((raise "not implemented"),(raise "not implemented")) from X;
  _back((raise "not implemented"),(raise "not implemented")) from X;
}

implementation iterable over hash of (%k,%v) determines %v is {
  _iterate(M,F,S) is __hash_iterate(M,F,S);
}

implementation indexed_iterable over hash of (%k,%v) determines (%k,%v) is {
  _ixiterate(M,F,S) is __hash_ix_iterate(M,F,S);
}